package com.ymx.darling.spring.mapper;

import com.ymx.darling.util.ResourceUtil;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.classreading.MetadataReader;

import java.util.Objects;
import java.util.Set;

/**
 * 继承自ClassPathBeanDefinitionScanner的Mapper扫描器，用于扫描并注册Mapper接口的Bean定义
 * @author 爱Java的小于
 */
public class MapperScanner extends ClassPathBeanDefinitionScanner {
    /**
     * 构造方法，传入Bean定义注册表
     * @param registry Bean定义注册表
     */
    public MapperScanner(BeanDefinitionRegistry registry) {
        super(registry);
    }

    /**
     * 重写isCandidateComponent方法，用于判断是否是候选组件
     * @param metadataReader 元数据读取器
     * @return 返回true表示所有组件都是候选组件
     */
    @Override
    protected boolean isCandidateComponent(MetadataReader metadataReader){
        return true;
    }

    /**
     * 重写isCandidateComponent方法，用于判断注解的Bean定义是否是候选组件
     * @param beanDefinition 注解的Bean定义
     * @return 只有当Bean定义是接口时才返回true
     */
    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return beanDefinition.getMetadata().isInterface();
    }

    /**
     * 执行扫描指定基础包下的组件
     * @param basePackages 基础包名数组
     * @return 返回扫描到的Bean定义持有者集合
     */
    @Override
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        // 调用父类的doScan方法扫描指定包下的组件
        Set<BeanDefinitionHolder> beanDefinitionHolders = super.doScan(basePackages);
        // 遍历扫描到的Bean定义持有者集合
        for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
            GenericBeanDefinition beanDefinition = (GenericBeanDefinition) beanDefinitionHolder.getBeanDefinition();
            // 添加构造器参数值
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(Objects.requireNonNull(beanDefinition.getBeanClassName()));
            String beanClassName = beanDefinition.getBeanClassName();
            try {
                // 根据类名获取Class对象
                Class<?> mapperClass = ResourceUtil.classForName(beanClassName);
                // 添加mapperClass属性值
                beanDefinition.getPropertyValues().add("mapperClass", mapperClass);
            } catch (ClassNotFoundException ignored) {
            }
            // 设置Bean类为MapperFactoryBean
            beanDefinition.setBeanClass(MapperFactoryBean.class);
            // 更改set方法注入模型
            beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        }
        return beanDefinitionHolders;
    }
}

